package service

import (
	"errors"
	"shopping/dao/mysql"
	"shopping/errno"
	"shopping/model"
)

// CartService 购物车service
type CartService struct {
	cartDao     *mysql.CartDao
	cartItemDao *mysql.ItemDao
	productDao  *mysql.ProductDao
}

// NewCartService 实例化
func NewCartService(cartDao *mysql.CartDao, cartItemDao *mysql.ItemDao, productDao *mysql.ProductDao) *CartService {
	return &CartService{
		cartDao:     cartDao,
		cartItemDao: cartItemDao,
		productDao:  productDao,
	}
}

// AddItem 添加Item
func (service *CartService) AddItem(userID int64, sku string, count int) error {
	currentProduct, err := service.productDao.FindBySku(sku)
	if err != nil {
		return err
	}
	currentCart, err := service.cartDao.FindOrCreateByUserId(userID)
	if err != nil {
		return err
	}
	_, err = service.cartItemDao.FindById(currentProduct.Id, currentCart.Id)
	if err == nil {
		return errno.ErrItemAlreadyExistInCart
	}
	if currentProduct.StockCount < count {
		return errno.ErrProductStockIsNotEnough
	}
	if count < 0 {
		return errno.ErrCountInvalid
	}
	err = service.cartItemDao.Create(model.NewCartItem(currentProduct.Id, currentCart.Id, count))
	return err
}

// 更新Item
func (service *CartService) UpdateItem(userId int64, sku string, count int) error {
	currentProduct, err := service.productDao.FindBySku(sku)
	if err != nil {
		return err
	}
	currentCart, err := service.cartDao.FindOrCreateByUserId(userId)
	if err != nil {
		return err
	}
	currentitem, err := service.cartItemDao.FindById(currentProduct.Id, currentCart.Id)
	if err != nil {
		return errors.New("item 不存在")
	}
	if currentProduct.StockCount < count {
		return errno.ErrProductStockIsNotEnough
	}
	currentitem.Count = count
	err = service.cartItemDao.Update(currentitem)
	return err
}

// GetCartItems 获得items
func (service *CartService) GetCartItems(userId int64) ([]model.Item, error) {
	currentCart, err := service.cartDao.FindOrCreateByUserId(userId)
	if err != nil {
		return nil, err
	}
	items, err := service.cartItemDao.GetItems(currentCart.Id)
	if err != nil {
		return nil, err
	}
	return items, nil
}
